package com.kehongborui.fliggy.util;

import com.alibaba.fastjson.JSON;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;

/**
 * @author zhang peng yang ming
 * @CopyRight (C) http://www.csdn.com
 * @brief
 * @email 122162005@qq.com
 * @date 2018-09-13
 */
public class ESClient {
    public static void main(String[] args) throws UnknownHostException {
        // 创建 es 的java 客户端
        TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
                .addTransportAddress(new TransportAddress(InetAddress.getByName("localhost"), 9300));

        Fruit fruit = new Fruit("四川浦江县猕猴桃 翠香绿心奇异果 ", "10块钱3斤", "不甜不要钱", "科宏博瑞");
//        getDoc(client, "by9R0mUBJzmzeBLcEHYt");
//        generateDoc(client, fruit);
        List<Fruit> fruits = search(Fruit.class, client);
        System.out.println(fruits);
        client.close();
    }

    /**
     * 利用客户端创建文档
     * @param o
     */
    public static void generateDoc(TransportClient client, Object o) {
        // 将对象转换成json
        String json = JSON.toJSONString(o);
        IndexResponse response = client.prepareIndex("trains", "fruit")
                .setSource(json, XContentType.JSON)
                .get();

        System.out.println(response.toString());
    }

    public static void getDoc(TransportClient client, String _id) {
        // 将对象转换成json
//        GetResponse response = client.prepareGet("trains", "fruit", "by9R0mUBJzmzeBLcEHYt").get();
        GetResponse response = client.prepareGet().get();
        System.out.println(response.getSource());
    }

    /**
     * 利用es java client 更改 document
     * @param client
     * @param index
     * @param type
     * @param id
     * @param o
     * @throws IOException
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void update(TransportClient client, String index, String type, String id, Object o) throws IOException, ExecutionException, InterruptedException {
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index(index);
        updateRequest.type(type);
        updateRequest.id(id);


        // 拼写要更改的内容（json）
        XContentBuilder builder = jsonBuilder()
                .startObject();

        // 通过反射机制获取 o 不为空的属性及名称
        Field[] fields = o.getClass().getFields();
        // 通过反射机制获取字段及值
        for (Field field : fields) {
            builder.field(field.getName(), "field.getValue()");
        }
//        builder.field("filedName", "fieldValue");
//        builder.field("filedName", "fieldValue");

        builder.endObject();
        updateRequest.doc(builder);

        UpdateResponse response = client.update(updateRequest).get();
        System.out.println(response);
    }

    /**
     * 实现关键词搜索
     * @param clazz
     * @param client
     * @param <T>
     * @return
     */
    public static <T>List<T> search(Class<T> clazz, TransportClient client) {
        SearchResponse response = client.prepareSearch("trains", "train")
                .setTypes("fruit", "_doc")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .setQuery(QueryBuilders.matchQuery("title", "猕猴桃"))                 // Query
//                .setPostFilter(QueryBuilders.rangeQuery("age").from(12).to(18))     // Filter
                .setFrom(0).setSize(60).setExplain(true)
                .get();

        List<T> result = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {

            T t = JSON.toJavaObject(JSON.parseObject(hit.getSourceAsString()), clazz);
            result.add(t);
        }

        return result;
    }
}


class Fruit{
    private String title;
    private String commnets;
    private String desc;
    private String store;

    public Fruit() {}

    public Fruit(String title, String commnets, String desc, String store) {
        this.title = title;
        this.commnets = commnets;
        this.desc = desc;
        this.store = store;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getCommnets() {
        return commnets;
    }

    public void setCommnets(String commnets) {
        this.commnets = commnets;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getStore() {
        return store;
    }

    public void setStore(String store) {
        this.store = store;
    }

    @Override
    public String toString() {
        return "Fruit{" +
                "title='" + title + '\'' +
                ", commnets='" + commnets + '\'' +
                ", desc='" + desc + '\'' +
                ", store='" + store + '\'' +
                '}';
    }
}